package com.enation.app.javashop.core.geo.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.enation.app.javashop.core.geo.model.*;
import com.enation.app.javashop.core.geo.service.GaodeManager;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.util.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;

import static org.assertj.core.util.Strings.append;

/**
 * @author JFeng
 * @date 2019/10/22 9:45
 */
@Service
public class GaodeManagerImpl implements GaodeManager {


    @Autowired(required = false)
    RestTemplate restTemplate;

    private final static String GAODE_MAP_KEY_POI = "837ef7c9293d938c2cc6745bdad4c390";


    /**
     * 地址正解析
     *
     * @param address  填写结构化地址信息:省份＋城市＋区县＋城镇＋乡村＋街道＋门牌号码
     * @param cityName 查询城市，可选：城市中文、中文全拼、citycode、adcode
     * @return 返回经纬度 lat,lng
     */
    @Override
    public GeoCode parseAddress(String address, String cityName) {
        // 优化 提高精度
        if (StringUtils.isNotEmpty(cityName) && !address.contains(cityName)) {
            address = cityName + address;
        }
        StringBuilder requestParam = new StringBuilder(GaodeMapConstant.GEO_URL);
        requestParam.append("?key=" + GAODE_MAP_KEY_POI)
                .append("&address=" + address)
                .append("&city=" + cityName);
        GaodeAddressResult result = restTemplate.getForObject(requestParam.toString(), GaodeAddressResult.class);
        if (CollectionUtils.isEmpty(result.getGeocodes())) {
            throw new ServiceException("1000", "高德地图解析异常,请确认输入地址信息：" + address.toString());
        }
        return result.getGeocodes().get(0);
    }


    /**
     * 根据POI逆解析 地址逆解析
     * https://restapi.amap.com/v3/geocode/regeo?output=xml&location=116.310003,39.991957&key=<用户的key>&radius=1000&extensions=all
     *
     * @param lng,lat 121.297619,31.204124    lat<纬度>,lng<经度>
     * @return 返回poi详细信息
     */
    @Override
    public RegeoCode parseLatLng(Double lng, Double lat) {
        if (lng == null || lat == null) {
            return new RegeoCode();
        }
        String lngLat = lng + "," + lat;
        StringBuilder requestParam = new StringBuilder(GaodeMapConstant.REGEO_URL);
        requestParam.append("?key=" + GAODE_MAP_KEY_POI)
                .append("&location=" + lngLat)
                .append("&extensions=all")
                .append("&output=json");
        String result = restTemplate.getForObject(requestParam.toString(), String.class);
        ParseLatLngResponse parseLatLngResponse = JSON.parseObject(result, new TypeReference<ParseLatLngResponse>() {
        });
        List<Pois> pois = parseLatLngResponse.getRegeocode().getPois();
        if(!CollectionUtils.isEmpty(pois)){
            for (Pois poi : pois) {
                String[] locationArray = poi.getLocation().split(",");
                poi.setLng(Double.valueOf(locationArray[0]));
                poi.setLat(Double.valueOf(locationArray[1]));
            }
        }
        return parseLatLngResponse.getRegeocode();
    }

    @Override
    public List<Pois> inputtips(String keyword) {
        if (StringUtils.isEmpty(keyword)) {
            return new ArrayList<>();
        }
        StringBuilder requestParam = new StringBuilder(GaodeMapConstant.INPUT_TIPS);
        requestParam.append("?key=" +GAODE_MAP_KEY_POI)
                .append("&offset=10")
                .append("&page=1")
                .append("&keywords=" + keyword)
                .append("&datatype=poi");
        String result = restTemplate.getForObject(requestParam.toString(), String.class);
        ParseKeywordResponse parseKeywordResponse = JSON.parseObject(result, new TypeReference<ParseKeywordResponse>() {
        });

        List<Pois> pois = parseKeywordResponse.getTips();
        List<Pois> correctPois =new ArrayList<>();
        if(!CollectionUtils.isEmpty(pois)){
            for (Pois poi : pois) {
                String location = poi.getLocation();
                if(!location.equals("[]")){
                    String[] locationArray = poi.getLocation().split(",");
                    poi.setLng(Double.valueOf(locationArray[0]));
                    poi.setLat(Double.valueOf(locationArray[1]));
                    correctPois.add(poi);
                }
            }
        }
        return correctPois;
    }

    @Override
    public double countDrivingDistance(String origin, String destination) {
        StringBuilder sb = new StringBuilder("http://restapi.amap.com/v3/direction/driving");
        sb.append("?key=" + GAODE_MAP_KEY_POI)
                .append("&origin=" + origin)
                .append("&destination=" + destination)
                .append("&strategy=" + 0)
                .append("&output=json");
        String resultJson = restTemplate.getForObject(sb.toString(), String.class);
        JSONObject jsonObject = JSON.parseObject(resultJson);
        if(jsonObject != null && "1".equals(jsonObject.getString("status"))){
            JSONObject route = jsonObject.getJSONObject("route");
            JSONObject result = route.getJSONArray("paths").getJSONObject(0);
            return Double.valueOf(result.getString("distance"));
        }
        return 0;
    }


}
